package org.flintparticles.common.stage3d
{
	import com.adobe.utils.AGALMiniAssembler;
	
	import flash.display3D.Context3D;
	import flash.display3D.Context3DProgramType;
	import flash.display3D.Program3D;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.utils.Dictionary;
	
	public class ShaderProgramManager extends EventDispatcher
	{
		private var _programs:Dictionary=new Dictionary();
		private var _context:Context3D;
		public function ShaderProgramManager(context:Context3D)
		{
			_context=context;
			
			initNames();
			initVertexShaders();
			initFragmentShaders();
			initStockPrograms();
			
			
		}
		public function getProgramByName(name:String):Program3D{
			return _programs[name];
		}
		//////////init the basic set of programs with default shader programs
		///for different types of rendering
		private var _vertexShaders:Vector.<String>=new Vector.<String>();
		private var _fragmentShaders:Vector.<String>=new Vector.<String>();
		private var _names:Vector.<String>=new Vector.<String>();
		public static const QUAD_PROGRAM:String="quad_program";
		public static const QUAD_PROGRAM_MVP:String="quad_program_mvp";
		public static const PARTICLE_BATCH_PROGRAM_MVP:String="particle_batch_program_mvp";
		public static const IMAGE_PROGRAM:String="texture_image_prgram";
		public static const MASSIVE_PARTICLES_PROG:String="massive_particle_prog";
		private function initNames():void{
			_names.push(QUAD_PROGRAM);
			_names.push(QUAD_PROGRAM_MVP);
			_names.push(PARTICLE_BATCH_PROGRAM_MVP);
			_names.push(IMAGE_PROGRAM);
			_names.push(MASSIVE_PARTICLES_PROG);
		}
		private function initVertexShaders():void{
			_vertexShaders.push(ShaderList.QUAD_VERT);
			_vertexShaders.push(ShaderList.QUAD_VERT_MTR);
			_vertexShaders.push(ShaderList.BATCH_QUAD_VERT_MTR_COL);
			_vertexShaders.push(ShaderList.IMAGE_VERT_MTR);
			_vertexShaders.push(ShaderList.MASS_VERT);
		}
		private function initFragmentShaders():void{
			_fragmentShaders.push(ShaderList.QUAD_FRAG);
			_fragmentShaders.push(ShaderList.QUAD_FRAG);
			_fragmentShaders.push(ShaderList.QUAD_FRAG);
			_fragmentShaders.push(ShaderList.IMAGE_FRAG);
			_fragmentShaders.push(ShaderList.MASS_FRAG);
		}
		private function initStockPrograms():void{
			var assembler:AGALMiniAssembler=new AGALMiniAssembler();
			for(var i:uint=0;i<_vertexShaders.length;++i){
				var program:Program3D = _context.createProgram();
				
				program.upload(
					assembler.assemble(Context3DProgramType.VERTEX,_vertexShaders[i]),
					assembler.assemble(Context3DProgramType.FRAGMENT,_fragmentShaders[i])
				);
			
				_programs[_names[i]]=program;		
			}
			
			           
			
		}
	}
}